package it.uniroma2.orchestrator;

import it.uniroma2.gestoreontologie.Gestore;
import it.uniroma2.model.wizard.Parametri;
import it.uniroma2.orchestrator.workflow.Nodo;
import it.uniroma2.orchestrator.workflow.Workflow;
import it.uniroma2.structure.Service;
import it.uniroma2.structure.tree.WorkflowTree;

import java.util.Hashtable;
import java.util.Vector;

public class Orchestrator {

	private Vector<Rule> ruleVect;
	private Vector<Regola> regole;
	private GestoreFile serializzatore;
	
	private Hashtable hashService;
	
	//Vector of all services
	private Vector<Service> vettoreServizi;
	
	private Vector<Service> vettoreServiziWorkflow;
	
	private Workflow workflow;
	private String domOnt;
	public static String servOnt;

	public Orchestrator(String servOnt) {
		/*
		 * this.serializzatore = new GestoreFile(); this.caricaRegole();
		 * Vector<Regola> r =
		 * (Vector<Regola>)this.serializzatore.caricaOggetto(); if(r != null){
		 * this.regole = r; }else{ this.regole = new Vector<Regola>(); }
		 */
		this.servOnt = servOnt;
		this.ruleVect = new Vector();
		this.vettoreServizi = new Vector();
		this.vettoreServiziWorkflow = new Vector();
		this.hashService = new Hashtable();
		this.generaServizi();
		this.findClassificators();
		

	}

	// Add a rule in the system
//	public void addRule(String domain, String value, String opclass,
//			String opinstance, String level) {
//
//		this.ruleVect.add(new Rule(domain, value, opclass, opinstance, level));
//	}

	// Generate a workflow from the rules
//	public void createWorkflow() {
//		for (int i = 0; i < this.ruleVect.size(); i++) {
//			Gestore gestoreDom = new Gestore(Parametri.NS_DOM,
//					domOnt);
//			Gestore gestoreSer = new Gestore(Parametri.NS,
//					Parametri.URI_SERVIZI);
//			Rule rule = ruleVect.elementAt(i);
//			String domain = rule.getDomain();
//			String value = rule.getValue();
//			String opclass = rule.getOpclass();
//			String opinstance = rule.getOpinstance();
//			String level = rule.getLevel();
//
//			Vector<String> indVect = gestoreDom.cercaIndividual(domain);
//			if (value.equalsIgnoreCase("*") && indVect.size() > 0) {
//				if (opinstance.compareTo("*") != 0) {
//					for (int j = 0; j < this.vettoreServizi.size(); j++) {
//						Service servizio = vettoreServizi.elementAt(j);
//						if (servizio.getNome().equalsIgnoreCase(opinstance)) {
//							servizio.rankCalc(level, domain);
//							this.vettoreServiziWorkflow.add(servizio);
//						}
//					}
//				} else {
//					Vector<String> serVect = gestoreSer
//							.cercaIndividual(opclass);
//					for (int j = 0; j < this.vettoreServizi.size(); j++) {
//						Service servizio = vettoreServizi.elementAt(j);
//						for (int k = 0; k < serVect.size(); k++) {
//							String tmp = serVect.elementAt(k).split("#")[1];
//							if (servizio.getNome().equalsIgnoreCase(tmp)) {
//								servizio.rankCalc(level, domain);
//								this.vettoreServiziWorkflow.add(servizio);
//							}
//						}
//
//					}
//				}
//			} else if (true) {
//				// TODO altre regole
//			}
//
//		}
//	}

	// This method checks all the dependencies of the services and add them in
	// the workflow
//	public Vector<Service> checkDependencies() {
//
//		Vector<Service> tmpVect = new Vector();
//		// Search for services, from highest to lowest rank
//		for (int i = 0; i < this.vettoreServiziWorkflow.size(); i++) {
//			if (tmpVect.isEmpty()) {
//				tmpVect.add(this.vettoreServiziWorkflow.elementAt(i));
//			} else {
//				Service tmpServ = this.vettoreServiziWorkflow.elementAt(i);
//				int tmpRank = tmpServ.getRank();
//				for (int j = 0; j < tmpVect.size(); j++) {
//					int tmpRank2 = tmpVect.elementAt(j).getRank();
//					if (tmpRank <= tmpRank2) {
//						tmpVect.add(j, tmpServ);
//						break;
//					}
//				}
//			}
//		}
//		// This vector is now ordered
//		this.vettoreServiziWorkflow = tmpVect;
//
//		// Add the needed services
//		Vector<Service> tmpServVect = new Vector();
//		while (!this.vettoreServiziWorkflow.isEmpty()) {
//
//			Service tmpServ = vettoreServiziWorkflow.lastElement();
//			this.vettoreServiziWorkflow.remove(this.vettoreServiziWorkflow
//					.size() - 1);
//			while (tmpServ.getNome().compareToIgnoreCase("Start") != 0) {
//				boolean flag = false;
//				tmpServVect.add(0 , tmpServ);
//				Vector<String> preC = tmpServ.getPreCondizione();
//				if (this.vettoreServiziWorkflow.isEmpty()) {
//					tmpServ = preC.firstElement();
//				} else {
//					for (int i = 0; i < preC.size(); i++) {
//						if (preC.elementAt(i)
//										.getNome()
//										.compareToIgnoreCase(
//												this.vettoreServiziWorkflow
//														.lastElement()
//														.getNome()) == 0) {
//							tmpServ = preC.elementAt(i);
//							flag = true;
//						}
//					}
//					if(flag){
//						flag = false;
//					} else {
//						tmpServ = preC.firstElement();
//					}
//				}
//			}
//
//		}
//		return tmpServVect;
//		
//
//	}
//
//	
//	
//	public void aggiungiRegola(String classe) {
//		this.regole.addElement(new Regola(classe));
//	}
//
//	public void salva() {
//		this.serializzatore.salvaOggetto(this.regole);
//	}
//
//	public void caricaRegole() {
//		this.regole = (Vector<Regola>) this.serializzatore.caricaOggetto();
//	}
//
	// Read service ontology and fill Service java Object
	public void generaServizi() {
		Gestore gestore = new Gestore(Parametri.NS, this.servOnt);
		Vector<String> istanze = gestore.cercaIndividual("Service");
		for (int i = 0; i < istanze.size(); i++) {
			if (istanze.elementAt(i) != null) {
				String nomeIns = istanze.elementAt(i).split("#")[1];
				Service tmp = new Service(nomeIns);
				this.hashService.put(nomeIns, tmp);
				this.vettoreServizi.addElement(tmp);
			}

		}
		

	}
	
	public void applyRules(String domOnt){
		this.domOnt = domOnt;
		
	}
	
	//This method applies rules to find classificators
	public void findClassificators(){
		//TODO inserire regole
		Service tmp = new Service("SVM_multi");
		tmp.setRank(1);
		this.vettoreServiziWorkflow.add(tmp);
	}
	
	public void applicaRegole() {
		for (int i = 0; i < this.regole.size(); i++) {
			Vector<String> vettoreClassi = null;
			for (int j = 0; j < vettoreClassi.size(); j++) {
				this.vettoreServiziWorkflow.add(this
						.stringToServizio(vettoreClassi.elementAt(j)));
			}
		}
	}

	public Service stringToServizio(String stringa) {
		for (int i = 0; i < this.vettoreServizi.size(); i++) {
			if (vettoreServizi.elementAt(i).getNome().compareTo(stringa) == 0) {
				return vettoreServizi.elementAt(i);
			}
		}
		return null;
	}

	public it.uniroma2.structure.Process createProcess(){
		WorkflowTree wft = new WorkflowTree(this.vettoreServiziWorkflow, this.vettoreServizi);
		
		return wft.createProcess(wft.listWorkflow.elementAt(4));
	}

	public Vector<Nodo> getWorkflow() {
		return this.workflow.getWorkflow();
	}

	public Vector<Service> getAllServices(){
		return this.vettoreServizi;
	}
	
	public Vector<Service> getAllServicesNoStartEnd(){
		Vector<Service> tmp = new Vector();
		for(Service serv : this.vettoreServizi){
			if(serv.getNome().equals("Start") || serv.getNome().equals("End")){
				
			} else tmp.add(serv);
		}
		return tmp;
	}


}
